home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / system / mail / transpor / ifmail23.z / ifmail23 / ifmail / ifgate / ifmail.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-10  |  6.5 KB  |  292 lines

  1. #include <sys/types.h>
  2. #include <unistd.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <ctype.h>
  7. #include <sys/stat.h>
  8. #include <sysexits.h>
  9. #ifdef HAS_SYSLOG
  10. #include <syslog.h>
  11. #endif
  12. #include "getopt.h"
  13. #include "lutil.h"
  14. #include "xutil.h"
  15. #include "ftn.h"
  16. #include "falists.h"
  17. #include "rfcmsg.h"
  18. #include "ftnmsg.h"
  19. #include "areas.h"
  20. #include "config.h"
  21. #include "version.h"
  22.  
  23. extern int newsmode;
  24. extern char *configname;
  25. extern char passwd[];
  26.  
  27. extern FILE *openpkt(faddr *,char);
  28. extern int putmessage(rfcmsg *,ftnmsg *,FILE *,FILE *,fa_list **);
  29. extern void closepkt(FILE *);
  30. extern char *bgets(char *,int,FILE *);
  31. extern void readareas(char *);
  32. extern void try_attach(char *,int,faddr *,char);
  33.  
  34. int usetmp=0;
  35. faddr *bestaka;
  36.  
  37. void usage(void)
  38. {
  39.     confusage("-n -r<addr> -g<grade> <recip> ...");
  40.     fprintf(stderr,"-n        set news mode\n");
  41.     fprintf(stderr,"-r<addr>    address to route packet\n");
  42.     fprintf(stderr,"-g<grade>    [ n | c | h ] \"flavor\" of packet\n");
  43.     fprintf(stderr,"<recip>        list of receipient addresses\n");
  44. }
  45.  
  46. int main(argc,argv)
  47. int argc;
  48. char *argv[];
  49. {
  50.     int c;
  51.     char *p;
  52.     char buf[BUFSIZ];
  53.     FILE *fp,*pkt = NULL;
  54.     char *routec=NULL;
  55.     faddr *route = NULL;
  56.     fa_list **envrecip, *envrecip_start = NULL;
  57.     int envrecip_count=0;
  58.     area_list *area = NULL, *area_start = NULL;
  59.     int area_count=0;
  60.     int msg_in=0,msg_out=0;
  61.     rfcmsg *msg=NULL,*tmsg;
  62.     ftnmsg *fmsg=NULL;
  63.     faddr *taddr;
  64.     char flavor='n';
  65.     fa_list *sbl = NULL;
  66.  
  67. #ifdef MAILLOG
  68.     logfacility=MAILLOG;
  69. #endif
  70.  
  71.     setmyname(argv[0]);
  72.     while ((c=getopt(argc,argv,"g:r:x:I:nh")) != -1)
  73.     if (confopt(c,optarg)) switch (c)
  74.     {
  75.         case 'g':    if (optarg && ((*optarg == 'n') || 
  76.                    (*optarg == 'c') || (*optarg == 'h')))
  77.                     flavor=*optarg;
  78.                 else 
  79.                 {
  80.                     usage(); 
  81.                     exit(EX_USAGE);
  82.                 }
  83.                 break;
  84.         case 'r':    routec=optarg; break;
  85.         case 'n':    newsmode=1; break;
  86.         default:    usage(); exit(EX_USAGE);
  87.     }
  88.  
  89.     if (readconfig())
  90.     {
  91.         fprintf(stderr,"Error getting configuration, aborting\n");
  92.         exit(EX_DATAERR);
  93.     }
  94.  
  95.     if ((routec) && ((route=parsefaddr(routec)) == NULL))
  96.         logerr("unparsable route address \"%s\"",routec);
  97.  
  98.     if ((p=strrchr(argv[0],'/'))) p++;
  99.     else p=argv[0];
  100.     if (!strcmp(p,"ifnews")) newsmode=1;
  101.  
  102.     if (newsmode)
  103.     {
  104.         readareas(areafile);
  105. #ifdef NEWSLOG
  106.         logfacility=NEWSLOG;
  107. #endif
  108.     }
  109.  
  110.     envrecip=&envrecip_start;
  111.     while (argv[optind])
  112.     if ((taddr=parsefaddr(argv[optind++]))) 
  113.     {
  114.         (*envrecip)=(fa_list*)xmalloc(sizeof(fa_list));
  115.         (*envrecip)->next=NULL;
  116.         (*envrecip)->addr=taddr;
  117.         envrecip=&((*envrecip)->next);
  118.         envrecip_count++;
  119.     }
  120.     else logerr("unparsable recipient \"%s\", ignored",argv[optind-1]);
  121.  
  122.     if ((!newsmode) && (!envrecip_count))
  123.     {
  124.         logerr("No valid receipients specified, aborting");
  125.         exit(EX_NOUSER);
  126.     }
  127.  
  128.     if (!route && newsmode && envrecip_count)
  129.         route=envrecip_start->addr;
  130.  
  131.     if (!route) route=parsefaddr(getenv("NEWSSITE"));
  132.  
  133.     if (!route)
  134.     {
  135.         logerr("Routing address not specified, aborting");
  136.         exit(EX_USAGE);
  137.     }
  138.  
  139.     bestaka=bestaka_s(route);
  140.  
  141.     for(envrecip=&envrecip_start;*envrecip;envrecip=&((*envrecip)->next))
  142.         loginf("envrecip: %s",ascfnode((*envrecip)->addr,0x7f));
  143.     loginf("route: %s",ascfnode(route,0x1f));
  144.  
  145.     umask(066); /* packets may contain confidential information */
  146.  
  147.     while (!feof(stdin))
  148.     {
  149.         usetmp=0;
  150.         tidyrfc(msg);
  151.         msg=parsrfc(stdin);
  152.  
  153.         if (pkt == NULL)
  154.         {
  155.             if (flavor == 'n') flavor='o';
  156.             if ((p=hdr("X-FTN-FLAGS",msg)))
  157.             {
  158.                 if (strstr(p,"CRS")) flavor='c';
  159.                 else if (strstr(p,"HLD")) flavor='h';
  160.                 if (strstr(p,"ATT"))
  161.                     try_attach(hdr("Subject",msg),0,route,flavor);
  162.                 if (strstr(p,"TFS"))
  163.                     try_attach(hdr("Subject",msg),1,route,flavor);
  164.                 if (strstr(p,"KFS"))
  165.                     try_attach(hdr("Subject",msg),2,route,flavor);
  166.             }
  167.             else if ((p=hdr("Priority",msg)) ||
  168.                      (p=hdr("X-Class",msg)))
  169.             {
  170.                 while (isspace(*p)) p++;
  171.                 if ((strncasecmp(p,"fast",4) == 0) ||
  172.                     (strncasecmp(p,"high",4) == 0) ||
  173.                     (strncasecmp(p,"crash",5) == 0))
  174.                     flavor='c';
  175.                 else if ((strncasecmp(p,"slow",4) == 0) ||
  176.                          (strncasecmp(p,"low",3) == 0) ||
  177.                          (strncasecmp(p,"hold",4) == 0))
  178.                     flavor='h';
  179.             }
  180.             if ((pkt=openpkt(route,flavor)) == NULL)
  181.             {
  182.                 logerr("Unable to open packet for node %s, aborting",
  183.                     ascfnode(route,0x1f));
  184.                 exit(EX_CANTCREAT);
  185.             }
  186.         }
  187.  
  188.         if (newsmode)
  189.         {
  190.             tidy_arealist(area_start);
  191.             area_start=areas(hdr("Newsgroups",msg));
  192.             area_count=0;
  193.             for(area=area_start;area;area=area->next)
  194.             {
  195.                 area_count++;
  196.                 debug(9,"area: %s",area->name);
  197.             }
  198.             tidy_falist(&sbl);
  199.             for (tmsg=msg;tmsg;tmsg=tmsg->next)
  200.                 if (strcasecmp(tmsg->key,"X-FTN-SEEN-BY") == 0)
  201.                     fill_list(&sbl,tmsg->val);
  202.         }
  203.  
  204.         if (((!newsmode) && (envrecip_count > 1)) ||
  205.             ((newsmode) && (area_count > 1)))
  206.         {
  207.             if ((fp=tmpfile()) == NULL)
  208.             {
  209.                 logerr("$Cannot open temporary file");
  210.                 exit(EX_OSERR);
  211.             }
  212.             while(bgets(buf,sizeof(buf)-1,stdin))
  213.                 fputs(buf,fp);
  214.             rewind(fp);
  215.             usetmp=1;
  216.         }
  217.         else
  218.         {
  219.             fp=stdin;
  220.             usetmp=0;
  221.         }
  222.  
  223.         if (newsmode && ((area_count < 1) || hdr("Control",msg) ||
  224.              (in_list(route,&sbl))))
  225.         {
  226.             debug(9,"skipping news message w/o valid newsgroups or Control header or seen by this node");
  227.             while(bgets(buf,sizeof(buf)-1,fp));
  228.         }
  229.         else
  230.         {
  231.             fill_list(&sbl,ascfnode(bestaka,0x06));
  232.             fill_list(&sbl,ascfnode(route,0x06));
  233.             tidy_ftnmsg(fmsg);
  234.             if ((fmsg=mkftnhdr(msg)) == NULL)
  235.             {
  236.                 logerr("Unable to create FTN headers from RFC ones, aborting");
  237.                 exit(EX_UNAVAILABLE);
  238.             }
  239.  
  240.             if (newsmode)
  241.             {
  242.                 fmsg->to->zone=route->zone;
  243.                 fmsg->to->net=route->net;
  244.                 fmsg->to->node=route->node;
  245.                 fmsg->to->point=route->point;
  246. #ifndef REAL_ADDRESS_IN_MSGHDR
  247.                 /* overwrite real "from" with our addr */
  248.                 fmsg->from->zone=bestaka->zone;
  249.                 fmsg->from->net=bestaka->net;
  250.                 fmsg->from->node=bestaka->node;
  251.                 fmsg->from->point=bestaka->point;
  252. #endif
  253.             }
  254.  
  255.             if (!newsmode)
  256.             for(envrecip=&envrecip_start;*envrecip;envrecip=&((*envrecip)->next))
  257.             {
  258.                 fmsg->to=(*envrecip)->addr;
  259.                 if (putmessage(msg,fmsg,fp,pkt,&sbl))
  260.                 {
  261.                     logerr("Unable to put netmail message into the packet, aborting");
  262.                     exit(EX_SOFTWARE);
  263.                 }
  264.                 if (usetmp) rewind(fp);
  265.                 fmsg->to=NULL;
  266.                 msg_out++;
  267.             }
  268.             else
  269.             for(area=area_start;area;area=area->next)
  270.             {
  271.                 fmsg->area=area->name;
  272.                 if (putmessage(msg,fmsg,fp,pkt,&sbl))
  273.                 {
  274.                     logerr("Unable to put echo message into the packet, aborting");
  275.                     exit(EX_SOFTWARE);
  276.                 }
  277.                 if (usetmp) rewind(fp);
  278.                 fmsg->area=NULL;
  279.                 msg_out++;
  280.             }
  281.             msg_in++;
  282.         }
  283.         if (usetmp) fclose(fp);
  284.     }
  285.  
  286.     closepkt(pkt);
  287.  
  288.     loginf("end input %d, output %d messages",msg_in,msg_out);
  289.  
  290.     return EX_OK;
  291. }
  292.